home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / c-lang / vbcc.lha / vbcc / statements.c < prev    next >
C/C++ Source or Header  |  1996-05-15  |  28KB  |  805 lines

  1. /*  $VER: vbcc (statements.c) V0.3  */
  2.  
  3. #include "vbc.h"
  4.  
  5. int cont_label=0;
  6. int test_assignment(struct Typ *,np);
  7.  
  8. void cr(void)
  9. /*  tested Registerbelegung */
  10. {
  11.     int i;
  12.     for(i=0;i<=MAXR;i++)
  13.         if(regs[i]!=regsa[i]) {error(149,regnames[i]);regs[i]=regsa[i];}
  14. }
  15. void statement(void)
  16. /*  bearbeitet ein statement                                    */
  17. {
  18.     char *merk;
  19.     cr();
  20.     killsp();
  21.     if(*s=='{'){
  22.         enter_block();
  23.         if(nesting>0) local_offset[nesting]=local_offset[nesting-1];
  24.         compound_statement();leave_block();return;}
  25.     merk=s;
  26.     cpbez(buff);
  27.     if(!strcmp("if",buff)){if_statement();return;}
  28.     if(!strcmp("switch",buff)){switch_statement();return;}
  29.     if(!strcmp("for",buff)){for_statement();return;}
  30.     if(!strcmp("while",buff)){while_statement();return;}
  31.     if(!strcmp("do",buff)){do_statement();return;}
  32.     if(!strcmp("goto",buff)){goto_statement();return;}
  33.     if(!strcmp("continue",buff)){continue_statement();return;}
  34.     if(!strcmp("break",buff)){break_statement();return;}
  35.     if(!strcmp("return",buff)){return_statement();return;}
  36.     if(!strcmp("case",buff)){labeled_statement();return;}
  37.     killsp();if(*s==':'){labeled_statement();return;}
  38.     /*  fehlt Aufruf der anderen statements */
  39.     s=merk;
  40.     expression_statement();
  41. }
  42. void labeled_statement(void)
  43. /*  bearbeitet labeled_statement                                */
  44. {
  45.     struct llist *lp;int def=0;
  46.     if(*s==':'){
  47.         s++;
  48.         if(!*buff){error(130);return;}
  49.         if(!strcmp("default",buff)){def=1;lp=0;} else lp=find_label(buff);
  50.         if(lp&&lp->flags&LABELDEFINED){error(131,buff);return;}
  51.         if(!lp) lp=add_label(buff);
  52.         lp->flags|=LABELDEFINED;
  53.         lp->switch_count=0;
  54.         if(def){
  55.             if(switch_act==0) error(150);
  56.             lp->flags|=LABELDEFAULT;
  57.             lp->switch_count=switch_act;
  58.         }
  59.         gen_label(lp->label);
  60.         afterlabel=0;
  61.     }else{
  62.         /*  case    */
  63.         np tree;struct llist *lp;
  64.         tree=expression();
  65.         killsp();
  66.         if(*s==':'){s++;killsp();} else error(70);
  67.         if(!switch_count){
  68.             error(132);
  69.         }else{
  70.             if(!tree||!type_expression(tree)){
  71.             }else{
  72.                 if(tree->flags!=CEXPR||tree->sidefx){
  73.                     error(133);
  74.                 }else{
  75.                     if((tree->ntyp->flags&15)<CHAR||(tree->ntyp->flags&15)>LONG){
  76.                         error(134);
  77.                     }else{
  78.                         lp=add_label(empty);
  79.                         lp->flags=LABELDEFINED;
  80.                         lp->switch_count=switch_act;
  81.                         eval_constn(tree);
  82.                         if(switch_typ==CHAR) lp->val.vchar=vchar;
  83.                         if(switch_typ==(UNSIGNED|CHAR)) lp->val.vuchar=vuchar;
  84.                         if(switch_typ==SHORT) lp->val.vshort=vshort;
  85.                         if(switch_typ==(UNSIGNED|SHORT)) lp->val.vushort=vushort;
  86.                         if(switch_typ==INT) lp->val.vint=vint;
  87.                         if(switch_typ==(UNSIGNED|INT)) lp->val.vuint=vuint;
  88.                         if(switch_typ==LONG) lp->val.vlong=vlong;
  89.                         if(switch_typ==(UNSIGNED|LONG)) lp->val.vulong=vulong;
  90.                         if(switch_typ==POINTER) lp->val.vpointer=vpointer;
  91.                         gen_label(lp->label);
  92.                     }
  93.                 }
  94.             }
  95.         }
  96.         if(tree) free_expression(tree);
  97.     }
  98.     cr();
  99.     killsp();
  100.     if(*s!='}') statement();
  101. }
  102. void if_statement(void)
  103. /*  bearbeitet if_statement                                     */
  104. {
  105.     int ltrue,lfalse,lout,cexpr,cm;char *merk,buff[MAXI];
  106.     np tree;struct IC *new;
  107.     killsp(); if(*s=='(') s++; else error(151);
  108.     killsp();cm=nocode;
  109.     tree=expression();
  110.     if(!tree) {error(135);
  111.     }else{
  112.         ltrue=++label;lfalse=++label;
  113.         if(type_expression(tree)){
  114.             tree=makepointer(tree);
  115.             if(!arith(tree->ntyp->flags&15)&&(tree->ntyp->flags&15)!=POINTER)
  116.                 {error(136);
  117.             }else{
  118.                 if(tree->flags==ASSIGN) error(164);
  119.                 gen_IC(tree,ltrue,lfalse);
  120.                 if(tree->flags==CEXPR){
  121.                     eval_const(&tree->val,tree->ntyp->flags&31);
  122.                     if(zdeq(vdouble)) cexpr=2; else cexpr=1;
  123.                 }else cexpr=0;
  124.                 if((tree->o.flags&SCRATCH)&&cexpr) free_reg(tree->o.reg);
  125.                 if(tree->o.flags&&!cexpr){
  126.                     new=(struct IC *)mymalloc(ICS);
  127.                     new->code=TEST;
  128.                     new->q1=tree->o;
  129.                     new->q2.flags=new->z.flags=0;
  130.                     new->typf=tree->ntyp->flags;
  131.                     add_IC(new);
  132.                     new=(struct IC *)mymalloc(ICS);
  133.                     new->code=BEQ;
  134.                     new->typf=lfalse;
  135.                     add_IC(new);
  136.                 }
  137.             }
  138.         }
  139.         free_expression(tree);
  140.     }
  141.     killsp(); if(*s==')') s++; else error(59);
  142.     if(cexpr==2) nocode=1;
  143.     if(!cexpr&&!tree->o.flags) gen_label(ltrue);
  144.     statement();
  145.     killsp();
  146.     merk=s;
  147.     cpbez(buff);
  148.     if(strcmp("else",buff)) {s=merk;nocode=cm;if(!cexpr) gen_label(lfalse);return;}
  149.     lout=++label;
  150.     if(!cexpr){
  151.         new=(struct IC *)mymalloc(ICS);
  152.         new->code=BRA;
  153.         new->typf=lout;
  154.         add_IC(new);
  155.         gen_label(lfalse);
  156.     }
  157.     if(cexpr==1) nocode=1; else nocode=cm;
  158.     statement();
  159.     if(!cexpr) gen_label(lout);
  160.     nocode=cm;
  161.     cr();
  162. }
  163. void switch_statement(void)
  164. /*  bearbeitet switch_statement                                 */
  165. {
  166.     np tree;int merk_typ,merk_count,merk_break;
  167.     struct IC *merk_fic,*merk_lic,*new;struct llist *lp,*l1,*l2;
  168.     killsp();
  169.     if(*s=='('){s++;killsp();} else error(151);
  170.     tree=expression(); killsp();
  171.     if(*s==')'){s++;killsp();} else error(59);
  172.     merk_typ=switch_typ;merk_count=switch_act;merk_break=break_label;
  173.     if(!tree){
  174.         error(137);
  175.     }else{
  176.         if(!type_expression(tree)){
  177.         }else{
  178.             if((tree->ntyp->flags&15)<CHAR||(tree->ntyp->flags&15)>LONG){
  179.                 error(138);
  180.             }else{
  181.                 int m1,m2,m3,def=0,rm,minflag;
  182.                 zlong l,ml,s;zulong ul,mul,us;
  183.                 if(tree->flags==ASSIGN) error(164);
  184.                 m3=break_label=++label;m1=switch_act=++switch_count;
  185.                 m2=switch_typ=tree->ntyp->flags&31;
  186.                 gen_IC(tree,0,0);
  187.                 if((tree->o.flags&(DREFOBJ|SCRATCH))!=SCRATCH){
  188.                     new=(struct IC *)mymalloc(ICS);
  189.                     new->code=ASSIGN;
  190.                     new->q1=tree->o;
  191.                     new->q2.flags=0;
  192.                     new->q2.reg=sizetab[m2&15];
  193.                     get_scratch(&new->z,m2,0);
  194.                     new->typf=m2;
  195.                     tree->o=new->z;
  196.                     add_IC(new);
  197.                 }
  198.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)){
  199.                     int r=tree->o.reg;
  200.                     rm=regs[r];
  201.                     regs[r]=regsa[r];
  202.                 }
  203.                 merk_fic=first_ic;merk_lic=last_ic;
  204.                 first_ic=last_ic=0;
  205.                 statement();
  206.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)) regs[tree->o.reg]=rm;
  207.                 minflag=0;s=l2zl(0L);us=ul2zul(0UL);
  208.                 for(l1=first_llist;l1;l1=l1->next){
  209.                     if(l1->switch_count!=m1) continue;
  210.                     if(l1->flags&LABELDEFAULT){
  211.                         if(def) error(139);
  212.                         def=l1->label;
  213.                         continue;
  214.                     }
  215.                     lp=0;minflag&=~1;
  216.                     for(l2=first_llist;l2;l2=l2->next){
  217.                         if(l2->switch_count!=m1) continue;
  218.                         if(l2->flags&LABELDEFAULT) continue;
  219.                         eval_const(&l2->val,m2);
  220.                         if(minflag&2){
  221.                             if(m2&UNSIGNED){
  222.                                 if(zulleq(vulong,mul)||zuleqto(vulong,mul)) continue;
  223.                             }else{
  224.                                 if(zlleq(vlong,ml)||zleqto(vlong,ml)) continue;
  225.                             }
  226.                         }
  227.                         if(minflag&1){
  228.                             if(m2&UNSIGNED){
  229.                                 if(!(minflag&4)&&zuleqto(vulong,ul)){ error(201);minflag|=4;}
  230.                                 if(zulleq(vulong,ul)){lp=l2;ul=vulong;}
  231.                             }else{
  232.                                 if(!(minflag&4)&&zleqto(vlong,l)){ error(201);minflag|=4;}
  233.                                 if(zlleq(vlong,l)){lp=l2;l=vlong;}
  234.                             }
  235.                         }else{
  236.                             minflag|=1;
  237.                             l=vlong;
  238.                             ul=vulong;
  239.                             lp=l2;
  240.                         }
  241.                     }
  242.                     if(!lp) continue;
  243.                     ml=l;mul=ul;minflag|=2;
  244.                     if(SWITCHSUBS){
  245.                         new=mymalloc(ICS);
  246.                         new->typf=m2;
  247.                         new->code=SUB;
  248.                         new->q1=tree->o;
  249.                         new->z=tree->o;
  250.                         new->q2.flags=KONST;
  251.                         eval_const(&lp->val,m2);
  252.                         vlong=zlsub(vlong,s);
  253.                         vulong=zulsub(vulong,us);
  254.                         vint=zl2zi(vlong);
  255.                         vshort=zl2zs(vlong);
  256.                         vchar=zl2zc(vlong);
  257.                         vuint=zul2zui(vulong);
  258.                         vushort=zul2zus(vulong);
  259.                         vuchar=zul2zuc(vulong);
  260.                         insert_const2(&new->q2.val,m2);
  261.                         new->q1.am=new->q2.am=new->z.am=0;
  262.                         s=l;us=ul;
  263.                         new->prev=merk_lic;
  264.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  265.                         merk_lic=new;
  266.                         new=mymalloc(ICS);
  267.                         new->typf=m2;
  268.                         new->code=TEST;
  269.                         new->q1=tree->o;
  270.                         new->q2.flags=new->z.flags=0;
  271.                         new->prev=merk_lic;
  272.                         new->q1.am=new->q2.am=new->z.am=0;
  273.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  274.                         merk_lic=new;
  275.                     }else{
  276.                         new=(struct IC *)mymalloc(ICS);
  277.                         new->code=COMPARE;
  278.                         new->typf=m2;
  279.                         new->q1=tree->o;
  280.                         new->q2.flags=KONST;
  281.                         new->q2.val=lp->val;
  282.                         new->z.flags=0;
  283.                         new->prev=merk_lic;
  284.                         new->q1.am=new->q2.am=new->z.am=0;
  285.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  286.                         merk_lic=new;
  287.                     }
  288.                     new=(struct IC *)mymalloc(ICS);
  289.                     new->code=BEQ;
  290.                     new->typf=lp->label;
  291.                     new->q1.flags=new->q2.flags=new->z.flags=0;
  292.                     new->prev=merk_lic;
  293.                     new->q1.am=new->q2.am=new->z.am=0;
  294.                     merk_lic->next=new;
  295.                     merk_lic=new;
  296.                 }
  297.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)){   /* free_reg(tree->o.reg); */
  298.                     new=(struct IC *)mymalloc(ICS);
  299.                     new->code=FREEREG;new->typf=0;
  300.                     new->q2.flags=new->z.flags=0;
  301.                     new->q1.flags=REG;
  302.                     new->q1.reg=tree->o.reg;
  303.                     new->prev=merk_lic;
  304.                     new->q1.am=new->q2.am=new->z.am=0;
  305.                     if(merk_lic) merk_lic->next=new; else merk_fic=new;
  306.                     merk_lic=new;
  307.                     regs[tree->o.reg]=regsa[tree->o.reg];
  308.                 }
  309.                 new=(struct IC *)mymalloc(ICS);
  310.                 new->code=BRA;
  311.                 if(def) new->typf=def; else new->typf=m3;
  312.                 new->q1.flags=new->q2.flags=new->z.flags=0;
  313.                 if(merk_lic) merk_lic->next=new; else merk_fic=new;
  314.                 new->prev=merk_lic;
  315.                 first_ic->prev=new;
  316.                 new->next=first_ic;
  317.                 new->q1.am=new->q2.am=new->z.am=0;
  318.                 first_ic=merk_fic;
  319.                 gen_label(m3);
  320.             }
  321.         }
  322.     }
  323.     switch_typ=merk_typ;switch_act=merk_count;break_label=merk_break;
  324.     if(tree) free_expression(tree);
  325.     cr();
  326. }
  327. void while_statement(void)
  328. /*  bearbeitet while_statement                                  */
  329. {
  330.     np tree;int lloop,lin,lout,cm,cexpr,contm,breakm;
  331.     struct IC *new;
  332.     killsp();
  333.     if(*s=='(') {s++;killsp();} else error(151);
  334.     tree=expression();killsp();
  335.     if(*s==')') {s++;killsp();} else error(59);
  336.     cexpr=0;
  337.     if(tree){
  338.         if(type_expression(tree)){
  339.             tree=makepointer(tree);
  340.             if(!arith(tree->ntyp->flags&15)&&(tree->ntyp->flags&15)!=POINTER){
  341.                 error(140);
  342.                 cexpr=-1;
  343.             }else{
  344.                 if(tree->flags==ASSIGN) error(164);
  345.                 if(tree->flags==CEXPR){
  346.                     eval_const(&tree->val,tree->ntyp->flags&31);
  347.                     if(zdeq(vdouble)) cexpr=1; else cexpr=2;
  348.                     if(cexpr==1) error(152);
  349.                 }
  350.             }
  351.         }else cexpr=-1;
  352.     } else error(141);
  353.     lloop=++label;lin=++label;lout=++label;cm=nocode;
  354.     contm=cont_label;breakm=break_label;
  355.     if(!cexpr||tree->sidefx) cont_label=lin; else cont_label=lloop;
  356.     if(!cexpr||tree->sidefx){
  357.         if(c_flags_val[0].l&2){ /*  bei Optimierung */
  358.             gen_IC(tree,lloop,lout);
  359.             if(tree->o.flags){
  360.                 new=(struct IC *)mymalloc(ICS);
  361.                 new->code=TEST;
  362.                 new->typf=tree->ntyp->flags&31;
  363.                 new->q1=tree->o;
  364.                 new->q2.flags=new->z.flags=0;
  365.                 add_IC(new);
  366.                 new=(struct IC *)mymalloc(ICS);
  367.                 new->code=BEQ;
  368.                 new->typf=lout;
  369.                 add_IC(new);
  370.             }
  371.         }else{
  372.             new=(struct IC *)mymalloc(ICS);
  373.             new->code=BRA;
  374.             new->typf=lin;
  375.             add_IC(new);
  376.         }
  377.     }
  378.     if(cexpr!=1) gen_label(lloop);
  379.     cm=nocode;break_label=lout;
  380.     if(cexpr==1) nocode=1;
  381.     currentpri*=looppri;
  382.     statement();
  383.     nocode=cm;cont_label=contm;break_label=breakm;
  384.     if(!cexpr||tree->sidefx) gen_label(lin);
  385.     if(tree&&cexpr>=0){
  386.         if(cexpr!=1||tree->sidefx){
  387.             gen_IC(tree,lloop,lout);
  388.             if((tree->o.flags&SCRATCH)&&cexpr) free_reg(tree->o.reg);
  389.         }
  390.         if(tree->o.flags&&!cexpr){
  391.             new=(struct IC *)mymalloc(ICS);
  392.             new->code=TEST;
  393.             new->typf=tree->ntyp->flags&31;
  394.             new->q1=tree->o;
  395.             new->q2.flags=new->z.flags=0;
  396.             add_IC(new);
  397.             new=(struct IC *)mymalloc(ICS);
  398.             new->code=BNE;
  399.             new->typf=lloop;
  400.             add_IC(new);
  401.         }
  402.         if(cexpr==2){
  403.             new=(struct IC *)mymalloc(ICS);
  404.             new->code=BRA;
  405.             new->typf=lloop;
  406.             add_IC(new);
  407.         }
  408.     }
  409.     if(tree) free_expression(tree);
  410.     gen_label(lout);
  411.     currentpri/=looppri;
  412.     cr();
  413. }
  414. void for_statement(void)
  415. /*  bearbeitet for_statement                                    */
  416. {
  417.     np tree1=0,tree2=0,tree3=0;int lloop,lin,lout,cm,cexpr,contm,breakm;
  418.     struct IC *new;
  419.     killsp();
  420.     if(*s=='(') {s++;killsp();} else error(59);
  421.     if(*s!=';'){tree1=expression();killsp();}
  422.     if(tree1){
  423.         if(tree1->flags==POSTINC) tree1->flags=PREINC;
  424.         if(tree1->flags==POSTDEC) tree1->flags=PREDEC;
  425.         if(type_expression(tree1)){
  426.             if(tree1->sidefx){
  427.                 gen_IC(tree1,0,0);
  428.                 if(tree1&&(tree1->o.flags&SCRATCH)) free_reg(tree1->o.reg);
  429.             }else{error(153);}
  430.         }
  431.         free_expression(tree1);
  432.     }
  433.     cexpr=0;
  434.     if(*s==';') {s++;killsp();} else error(54);
  435.     if(*s!=';') {tree2=expression();killsp();} else {cexpr=2;}
  436.     if(*s==';') {s++;killsp();} else error(54);
  437.     if(*s!=')') {tree3=expression();killsp();}
  438.     if(*s==')') {s++;killsp();} else error(59);
  439.     if(tree3){
  440.         if(!type_expression(tree3)){
  441.             free_expression(tree3);
  442.             tree3=0;
  443.         }
  444.     }
  445.     if(tree2){
  446.         if(type_expression(tree2)){
  447.             tree2=makepointer(tree2);
  448.             if(!arith(tree2->ntyp->flags&15)&&(tree2->ntyp->flags&15)!=POINTER){
  449.                 error(142);
  450.                 cexpr=-1;
  451.             }else{
  452.                 if(tree2->flags==ASSIGN) error(164);
  453.                 if(tree2->flags==CEXPR){
  454.                     eval_const(&tree2->val,tree2->ntyp->flags&31);
  455.                     if(zdeq(vdouble)) cexpr=1; else cexpr=2;
  456.                     if(cexpr==1) error(152);
  457.                 }
  458.             }
  459.         }else cexpr=-1;
  460.     }
  461.     lloop=++label;lin=++label;lout=++label;cm=nocode;
  462.     contm=cont_label;breakm=break_label;
  463.     cont_label=++label;break_label=lout;
  464.     if(!cexpr||(tree2&&tree2->sidefx)){
  465.         if(c_flags_val[0].l&2){ /*  bei Optimierung */
  466.             gen_IC(tree2,lloop,lout);
  467.             if(tree2->o.flags){
  468.                 new=(struct IC *)mymalloc(ICS);
  469.                 new->code=TEST;
  470.                 new->typf=tree2->ntyp->flags&31;
  471.                 new->q1=tree2->o;
  472.                 new->q2.flags=new->z.flags=0;
  473.                 add_IC(new);
  474.                 new=(struct IC *)mymalloc(ICS);
  475.                 new->code=BEQ;
  476.                 new->typf=lout;
  477.                 add_IC(new);
  478.             }
  479.         }else{
  480.             new=(struct IC *)mymalloc(ICS);
  481.             new->code=BRA;
  482.             new->typf=lin;
  483.             add_IC(new);
  484.         }
  485.     }
  486.     if(cexpr!=1) gen_label(lloop);
  487.     cm=nocode;
  488.     if(cexpr==1) nocode=1;
  489.     currentpri*=looppri;
  490.     statement();
  491.     nocode=cm;
  492.     gen_label(cont_label);
  493.     cont_label=contm;break_label=breakm;
  494.     if(tree3){
  495.         if(tree3->flags==POSTINC) tree3->flags=PREINC;
  496.         if(tree3->flags==POSTDEC) tree3->flags=PREDEC;
  497.         if(tree3->sidefx){
  498.             gen_IC(tree3,0,0);
  499.             if(tree3&&(tree3->o.flags&SCRATCH)) free_reg(tree3->o.reg);
  500.         }else error(153);
  501.         free_expression(tree3);
  502.     }
  503.     if(!cexpr||(tree2&&tree2->sidefx)) gen_label(lin);
  504.     if(tree2&&cexpr>=0){
  505.         if(cexpr!=1||tree2->sidefx){
  506.             gen_IC(tree2,lloop,lout);
  507.             if((tree2->o.flags&SCRATCH)&&cexpr) free_reg(tree2->o.reg);
  508.         }
  509.         if(tree2->o.flags&&!cexpr){
  510.             new=(struct IC *)mymalloc(ICS);
  511.             new->code=TEST;
  512.             new->typf=tree2->ntyp->flags&31;
  513.             new->q1=tree2->o;
  514.             new->q2.flags=new->z.flags=0;
  515.             add_IC(new);
  516.             new=(struct IC *)mymalloc(ICS);
  517.             new->code=BNE;
  518.             new->typf=lloop;
  519.             add_IC(new);
  520.         }
  521.         if(cexpr==2){
  522.             new=(struct IC *)mymalloc(ICS);
  523.             new->code=BRA;
  524.             new->typf=lloop;
  525.             add_IC(new);
  526.         }
  527.     }
  528.     if(!tree2&&cexpr==2){
  529.         new=(struct IC *)mymalloc(ICS);
  530.         new->code=BRA;
  531.         new->typf=lloop;
  532.         add_IC(new);
  533.     }
  534.     if(tree2) free_expression(tree2);
  535.     gen_label(lout);
  536.     currentpri/=looppri;
  537.     cr();
  538. }
  539. void do_statement(void)
  540. /*  bearbeitet do_statement                                     */
  541. {
  542.     np tree;int lloop,lout,contm,breakm;
  543.     struct IC *new;
  544.     lloop=++label;lout=++label;currentpri*=looppri;
  545.     gen_label(lloop);
  546.     breakm=break_label;contm=cont_label;cont_label=++label;break_label=lout;
  547.     statement();
  548.     killsp();
  549.     gen_label(cont_label);cont_label=contm;break_label=breakm;
  550.     cpbez(buff);killsp();
  551.     if(strcmp("while",buff)) error(154);
  552.     if(*s=='(') {s++;killsp();} else error(151);
  553.     tree=expression();
  554.     if(tree){
  555.         if(type_expression(tree)){
  556.             tree=makepointer(tree);
  557.             if(arith(tree->ntyp->flags&15)||(tree->ntyp->flags&15)==POINTER){
  558.                 if(tree->flags==ASSIGN) error(164);
  559.                 if(tree->flags==CEXPR){
  560.                     eval_const(&tree->val,tree->ntyp->flags&31);
  561.                     if(tree->sidefx) gen_IC(tree,0,0);
  562.                     if(!zdeq(vdouble)){
  563.                         new=(struct IC *)mymalloc(ICS);
  564.                         new->code=BRA;
  565.                         new->typf=lloop;
  566.                         add_IC(new);
  567.                     }
  568.                 }else{
  569.                     gen_IC(tree,lloop,lout);
  570.                     if(tree->o.flags){
  571.                         new=(struct IC *)mymalloc(ICS);
  572.                         new->code=TEST;
  573.                         new->typf=tree->ntyp->flags&31;
  574.                         new->q1=tree->o;
  575.                         new->q2.flags=new->z.flags=0;
  576.                         add_IC(new);
  577.                         new=(struct IC *)mymalloc(ICS);
  578.                         new->code=BNE;
  579.                         new->typf=lloop;
  580.                         add_IC(new);
  581.                     }
  582.                 }
  583.             }else error(143);
  584.         }
  585.         free_expression(tree);
  586.     }
  587.     killsp();
  588.     if(*s==')') {s++;killsp();} else error(59);
  589.     if(*s==';') {s++;killsp();} else error(54);
  590.     gen_label(lout);
  591.     currentpri/=looppri;
  592.     cr();
  593. }
  594. void goto_statement(void)
  595. /*  bearbeitet goto_statement                                   */
  596. {
  597.     struct llist *lp;
  598.     struct IC *new;
  599.     killsp();cpbez(buff);
  600.     if(!*buff) error(144);
  601.     killsp();
  602.     if(*s==';'){s++;killsp();} else error(54);
  603.     lp=find_label(buff);
  604.     if(!lp) lp=add_label(buff);
  605.     lp->flags|=LABELUSED;
  606.     new=(struct IC *)mymalloc(ICS);
  607.     new->typf=lp->label;
  608.     new->code=BRA;
  609.     new->typf=lp->label;
  610.     add_IC(new);
  611.     cr();
  612.     goto_used=1;
  613. }
  614. void continue_statement(void)
  615. /*  bearbeitet continue_statement                               */
  616. {
  617.     struct IC *new;
  618.     killsp();
  619.     if(*s==';') {s++;killsp();} else error(54);
  620.     if(cont_label==0){error(145);return;}
  621.     new=(struct IC *)mymalloc(ICS);
  622.     new->code=BRA;
  623.     new->typf=cont_label;
  624.     add_IC(new);
  625.     cr();
  626. }
  627. void break_statement(void)
  628. /*  bearbeitet break_statement                                  */
  629. {
  630.     struct IC *new;
  631.     killsp();
  632.     if(*s==';') {s++;killsp();} else error(54);
  633.     if(break_label==0){error(146);return;}
  634.     new=(struct IC *)mymalloc(ICS);
  635.     new->code=BRA;
  636.     new->typf=break_label;
  637.     add_IC(new);
  638.     cr();
  639. }
  640. extern int has_return;
  641. void return_statement(void)
  642. /*  bearbeitet return_statement                                 */
  643. /*  SETRETURN hat Groesse in q2.reg und z.reg==freturn(rtyp)    */
  644. {
  645.     np tree;
  646.     struct IC *new;
  647.     has_return=1;
  648.     killsp();
  649.     if(*s!=';'){
  650.         if(tree=expression()){
  651.             killsp();
  652.             if(*s==';') {s++;killsp();} else error(54);
  653.             if(!return_typ){
  654.                 if(type_expression(tree)){
  655.                     tree=makepointer(tree);
  656.                     if((tree->ntyp->flags&15)!=VOID)
  657.                         error(155);
  658.                     gen_IC(tree,0,0);
  659.                     if(tree->o.flags&SCRATCH) free_reg(tree->o.reg);
  660.                 }
  661.             }else{
  662.                 if(type_expression(tree)){
  663.                     tree=makepointer(tree);
  664.                     if(!test_assignment(return_typ,tree)){free_expression(tree);return;}
  665.                     gen_IC(tree,0,0);
  666.                     convert(tree,return_typ->flags&31);
  667. #ifdef OLDPARMS   /*  alte CALL/RETURN-Methode    */
  668.                     new=(struct IC *)mymalloc(ICS);
  669.                     new->code=ASSIGN;
  670.                     new->typf=return_typ->flags&31;
  671.                     new->q1=tree->o;
  672.                     new->q2.flags=0;
  673.                     new->q2.reg=szof(return_typ);
  674.                     if(freturn(return_typ)){
  675.                         new->z.flags=SCRATCH|REG;
  676.                         new->z.reg=freturn(return_typ);
  677.                         if(!regs[new->z.reg]){
  678.                             struct IC *alloc=mymalloc(ICS);
  679.                             alloc->code=ALLOCREG;
  680.                             alloc->q1.flags=REG;
  681.                             alloc->q2.flags=alloc->z.flags=0;
  682.                             alloc->q1.reg=new->z.reg;
  683.                             regs[new->z.reg]=1;
  684.                             add_IC(alloc);
  685.                         }
  686.                     }else{
  687.                         new->z.reg=0;
  688.                         new->z.v=return_var;
  689.                         new->z.flags=SCRATCH|VAR;
  690.                         new->z.val.vlong=l2zl(0L);
  691.                     }
  692.                     add_IC(new);
  693.                     /*  das hier ist nicht sehr schoen, aber wie sonst? */
  694.                     if(new->z.flags&SCRATCH&®s[new->z.reg]) free_reg(new->z.reg);
  695. #else
  696.                     new=mymalloc(ICS);
  697.                     if(return_var){ /*  Returnwert ueber Zeiger */
  698.                         new->code=ASSIGN;
  699.                         new->z.flags=VAR|DREFOBJ;
  700.                         new->z.val.vlong=l2zl(0L);
  701.                         new->z.v=return_var;
  702.                     }else{
  703.                         new->code=SETRETURN;
  704.                         new->z.reg=freturn(return_typ);
  705.                         new->z.flags=0;
  706.                     }
  707.                     new->typf=return_typ->flags&31;
  708.                     new->q1=tree->o;
  709.                     new->q2.flags=0;
  710.                     new->q2.reg=szof(return_typ);
  711.                     add_IC(new);
  712. #endif
  713.                 }
  714.             }
  715.             free_expression(tree);
  716.         }else{
  717.             if(return_typ) error(156);
  718.         }
  719.     }else{ s++; if(return_typ) error(156);}
  720.  
  721.     new=(struct IC *)mymalloc(ICS);
  722.     new->code=BRA;
  723.     new->typf=return_label;
  724.     add_IC(new);
  725.     cr();
  726. }
  727.  
  728. void expression_statement(void)
  729. /*  bearbeitet expression_statement                             */
  730. {
  731.     np tree;
  732.     killsp();
  733.     if(*s==';') {s++;return;}
  734.     if(tree=expression()){
  735.         if(tree->flags==POSTINC) tree->flags=PREINC;
  736.         if(tree->flags==POSTDEC) tree->flags=PREDEC;
  737.         if(type_expression(tree)){
  738.             if(DEBUG&2){pre(stdout,tree);printf("\n");}
  739.             if(tree->sidefx){
  740.                 gen_IC(tree,0,0);
  741.                 if((tree->o.flags&(SCRATCH|REG))==REG) ierror(0);
  742.                 if(tree&&(tree->o.flags&SCRATCH)) free_reg(tree->o.reg);
  743.             }else{error(153);if(DEBUG&2) prd(stdout,tree->ntyp);}
  744.         }
  745.         free_expression(tree);
  746.     }
  747.     killsp();
  748.     if(*s==';') s++; else error(54);
  749.     cr();
  750. }
  751. void compound_statement(void)
  752. /*  bearbeitet compound_statement (block)                       */
  753. {
  754.     killsp();
  755.     if(*s=='{') s++; else error(157);
  756.     killsp();
  757.     while(declaration(0)){
  758.         var_declaration();
  759.         killsp();
  760.     }
  761.     while(*s!='}'){
  762.         statement();
  763.         killsp();
  764.     }
  765.     s++;killsp();
  766. }
  767. struct llist *add_label(char *identifier)
  768. /*  Fuegt label in Liste                                        */
  769. {
  770.     struct llist *new;
  771.     new=(struct llist *)mymalloc(LSIZE);
  772.     new->next=0;new->label=++label;new->flags=0;
  773.     new->identifier=add_identifier(identifier,strlen(identifier));
  774.     if(first_llist==0){
  775.         first_llist=last_llist=new;
  776.     }else{
  777.         last_llist->next=new;
  778.         last_llist=new;
  779.     }
  780.     return(last_llist); /* return(new) sollte aequiv. sein */
  781. }
  782. struct llist *find_label(char *identifier)
  783. /*  Sucht Label, gibt Zeiger auf llist oder 0 beu Fehler zurueck    */
  784. {
  785.     struct llist *p;
  786.     p=first_llist;
  787.     while(p){
  788.         if(!strcmp(p->identifier,identifier)) return(p);
  789.         p=p->next;
  790.     }
  791.     return(0);
  792. }
  793. void free_llist(struct llist *p)
  794. /*  Gibt llist frei                                             */
  795. {
  796.     struct llist *merk;
  797.     while(p){
  798.         merk=p->next;
  799.         if(!(p->flags&LABELDEFINED)) error(147,p->identifier);
  800.         if(!(p->flags&LABELUSED)&&!p->switch_count) error(148,p->identifier);
  801.         free(p);
  802.         p=merk;
  803.     }
  804. }
  805.